'use strict';
var restful = require('../../common/utils/restful')
var util = require('../../common/utils/util')

module.exports = function (app) {
    var sys_smscode = app.models.sys_smscode;
    var sys_user = app.models.sys_user;
    var AccessToken = app.models.AccessToken;
    var sys_user_info = app.models.sys_user_info;
    var sys_user_employment = app.models.sys_user_employment;
    var sys_user_graduation = app.models.sys_user_graduation;

    var loginWithSmscode = function (access_token, appid, mobile, smscode, ip, next) {
        var rest = {
            code: restful.statusCode.INVALID_REQUEST,
            msg: 'sms code is wrong!',
            error: 'login failed!',
            data: null
        }

        sys_smscode.find({
            where: {
                and: [{
                        mobile: mobile
                    },
                    {
                        app_id: appid
                    },
                    {
                        code: smscode
                    },
                    {
                        tag: 'Login'
                    }
                ]
            },
            order: 'send_date desc'
        }, function (err, smscode_results) {
            if (err) {
                console.log(err);
                return next(null, rest);
            }
            if (smscode_results.length <= 0) {
                return next(null, rest);
            }

            var smscodeData = smscode_results[0];

            if (smscodeData.used) {
                rest.error = 'smscode used!'
                rest.msg = 'sorry , but this smscode has been used , please resend!'
                return next(null, rest)
            }

            sys_user.find({
                where: {
                    mobile: mobile
                },
                order: 'id desc'
            }, function (err, user_results) {
                if (err) {
                    console.log(err)
                    rest.msg = 'user login failed!'
                    rest.error = 'database exception'
                    return next(null, rest)
                }

                var userData = user_results[0];
                if (!userData && !access_token) {
                    rest.msg = 'user no exists, please register first!'
                    rest.error = 'login failed!'
                    return next(null, rest)
                }

                if (access_token) {
                    AccessToken.resolve(access_token, function (err, token) {
                        if (!token) {
                            rest.msg = 'token is wrong!'
                            return next(null, rest)
                        }
                        sys_user.find({
                            where: {
                                id: token.userId
                            }
                        }, function (err, wxuser_results) {
                            if (err) {
                                console.log(err)
                                rest.msg = 'user login failed';
                                rest.error = 'database exception';
                                return next(null, rest)
                            }
                            if (wxuser_results.length <= 0) {
                                rest.msg = 'user is not found!';
                                return next(null, rest)
                            }
                            var wxuserData = wxuser_results[0]

                            //当微信用户的TOKEN已经绑定了手机以后
                            //并且用户登录的手机号与传过来的access token不一致
                            //不存在手机号的情况下，证明该微信未注册过，则绑定到登录的这个号上
                            if (wxuserData.mobile) {
                                if (wxuserData.mobile !== mobile) {
                                    rest.msg = 'sorry , wechat is bind another mobile!'
                                    rest.error = 'login failed!'
                                    return next(null, rest);
                                } else {
                                    rest.code = restful.statusCode.OK
                                    rest.msg = 'success'
                                    rest.error = '';
                                    rest.data = {
                                        token: token,
                                        user: wxuserData
                                    }
                                    smscodeData.used = true;
                                    smscodeData.save();
                                    return next(null, rest)
                                }
                            }
                            userData.wx_openid = wxuserData.wx_openid;
                            userData.wx_unionid = wxuserData.wx_unionid;
                            userData.wx_appid = wxuserData.wx_appid;
                            userData.exprise_in = wxuserData.exprise_in;
                            userData.wx_accesstoken = wxuserData.wx_accesstoken;
                            userData.wx_refresh_token = wxuserData.wx_refresh_token;
                            userData.last_login_date = new Date();
                            userData.last_login_ip = ip
                            userData.save(null, function (err, model) {
                                wxuserData.destroy();
                                userData.createAccessToken(60 * 60 * 24, function (err, token) {
                                    rest.code = restful.statusCode.OK
                                    rest.msg = 'success'
                                    rest.error = ''
                                    rest.data = {
                                        token: token,
                                        user: wxuserData
                                    }
                                    smscodeData.used = true;
                                    smscodeData.save();
                                    return next(null, rest)
                                })
                            });
                        })
                    });
                } else {
                    userData.createAccessToken(60 * 60 * 24, function (err, token) {
                        rest.code = restful.statusCode.OK
                        rest.msg = 'success';
                        rest.error = ''
                        rest.data = {
                            token: token,
                            user: userData
                        };
                        smscodeData.used = true;
                        smscodeData.save();
                        userData.last_login_date = new Date();
                        userData.last_login_ip = ip
                        return next(null, rest);
                    })
                }
            })
        })
    }

    var loginWithPassword = function (access_token, appid, mobile, password, ip, next) {
        var rest = {
            code: restful.statusCode.INTERNAL_SERVER_ERROR,
            msg: 'login failed!',
            error: 'database exception!',
            data: null
        }
        sys_user.find({
            where: {
                and: [{
                        username: mobile
                    },
                    {
                        appid: appid
                    }
                ]
            }
        }, function (err, user_results) {
            if (err)
                return next(null, rest)
            if (user_results.length <= 0) {
                rest.msg = 'mobile `' + mobile + '` is not found , please register first!';
                rest.error = 'login failed!'
                return next(null, rest)
            }
            var userData = user_results[0]

            if (access_token) {
                AccessToken.resolve(access_token, function (err, token) {
                    if (!token) {
                        rest.msg = 'token is wrong!'
                        return next(null, rest)
                    }
                    sys_user.find({
                        where: {
                            id: token.userId
                        }
                    }, function (err, wxuser_results) {
                        if (err) {
                            console.log(err)
                            rest.msg = 'user login failed';
                            rest.error = 'database exception';
                            return next(null, rest)
                        }
                        if (wxuser_results.length <= 0) {
                            rest.msg = 'user is not found!';
                            return next(null, rest)
                        }
                        var wxuserData = wxuser_results[0]

                        //当微信用户的TOKEN已经绑定了手机以后
                        //并且用户登录的手机号与传过来的access token不一致
                        //不存在手机号的情况下，证明该微信未注册过，则绑定到登录的这个号上
                        if (wxuserData.mobile) {
                            if (wxuserData.mobile !== mobile) {
                                rest.msg = 'sorry , wechat is bind another mobile!'
                                rest.error = 'login failed!'
                                return next(null, rest);
                            } else {
                                wxuserData.hasPassword(hasPassword, function (err, confirm) {
                                    if (err || !confirm) {
                                        rest.code = restful.statusCode.OK
                                        rest.msg = 'success'
                                        rest.error = '';
                                        rest.data = {
                                            token: token,
                                            user: wxuserData
                                        }
                                        return next(null, rest)
                                    } else {
                                        wxuserData.createAccessToken(60 * 60 * 24, function (err, token) {
                                            rest.code = restful.statusCode.OK
                                            rest.msg = 'success'
                                            rest.error = ''
                                            rest.data = {
                                                token: token,
                                                user: wxuserData
                                            }
                                            return next(null, rest)
                                        })
                                    }
                                })
                            }
                        }
                        userData.wx_openid = wxuserData.wx_openid;
                        userData.wx_unionid = wxuserData.wx_unionid;
                        userData.wx_appid = wxuserData.wx_appid;
                        userData.exprise_in = wxuserData.exprise_in;
                        userData.wx_accesstoken = wxuserData.wx_accesstoken;
                        userData.wx_refresh_token = wxuserData.wx_refresh_token;
                        userData.last_login_date = new Date();
                        userData.last_login_ip = ip
                        userData.save(null, function (err, model) {
                            wxuserData.destroy();
                            userData.createAccessToken(60 * 60 * 24, function (err, token) {
                                rest.code = restful.statusCode.OK
                                rest.msg = 'success'
                                rest.error = ''
                                rest.data = {
                                    token: token,
                                    user: wxuserData
                                }
                                return next(null, rest)
                            })
                        });
                    })
                });
            } else {
                userData.hasPassword(password, function (err, confirm) {
                    if (err || !confirm) {
                        rest.msg = 'sorry , your password is not match!'
                        rest.error = 'login failed!'
                        return next(null, rest)
                    }
                    userData.createAccessToken(60 * 60 * 24, function (err, token) {
                        if (token) {
                            rest.code = restful.statusCode.OK
                            rest.msg = 'success'
                            rest.error = ''
                            rest.data = {
                                token: token,
                                user: userData
                            }

                            return next(null,rest);
                        }
                    })
                })
            }
        })
    }

    //手机号注册
    var regWithMobile = function (access_token, appid, mobile, realname, password, confirm_pass, smscode, ip, next) {
        var rest = {
            code: restful.statusCode.OK,
            msg: 'success',
            error: '',
            data: null
        }
        if (!appid) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'appId is required!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }
        if (!mobile) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'mobile is required!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }
        if (!util.is_mobile) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'mobile is Illegal!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }
        if (!password) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'password is required!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }
        if (password.length < 6 || password.length > 12) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'password length must be 6-12 char!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }
        if (confirm_pass !== password) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'confirm pass not equal password!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }
        if (realname.length < 3 || realname.length > 12) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'real name must be 3-12 char!',
                error: 'params failed',
                data: null
            }
            return next(null, rest)
        }

        sys_smscode.find({
            where: {
                and: [{
                    app_id: appid
                }, {
                    mobile: mobile
                }, {
                    tag: "Reg"
                }]
            },
            order: 'send_date desc'
        }, function (err, smscode_results) {
            rest = {
                code: restful.statusCode.INVALID_REQUEST,
                msg: 'system exception',
                error: 'real name must be 3-12 char!',
                data: null
            }

            if (err) {
                console.log(err)
                rest.error = 'system database exception!'
                rest.msg = 'verify smscode error , check api!'
                return next(null, rest)
            }
            if (smscode_results.length <= 0) {
                rest.error = 'param failed!'
                rest.msg = 'sms code can‘t be found ，please make sure is send!'
                return next(null, rest)
            }
            var smscodeData = smscode_results[0];
            if (smscodeData.code !== smscode) {
                rest.error = 'param failed!'
                rest.msg = 'verify sms code is failed , please check you sms code!'
                return next(null, {
                    res: rest
                })
            }

            if (smscodeData.used) {
                rest.error = 'smscode used!'
                rest.msg = 'sorry , but this smscode has been used , please resend!'
                return next(null, rest)
            }

            //检查手机号是否被注册
            sys_user.find({
                where: {
                    and: [{

                            app_id: appid
                        },
                        {
                            mobile: mobile
                        }
                    ]
                }
            }, function (err, mobile_user_results) {
                if (mobile_user_results.length > 0) {
                    var userData = mobile_user_results[0];
                    return userData.createAccessToken(60 * 60 * 24, function (err, token) {
                        smscodeData.used = true;
                        smscodeData.save();

                        rest.code = restful.statusCode.OK
                        rest.data = {
                            token: token,
                            user: userData
                        }
                        rest.msg = 'success'
                        rest.error = ''

                        userData.last_login_date = new Date()
                        userData.last_login_ip = ip

                        userData.save();

                        next(null, rest);
                    });
                }

                if (access_token) {
                    AccessToken.resolve(access_token, function (err, accessToken) {
                        if (err || !accessToken) {
                            rest.error = 'token failed';
                            rest.msg = 'access token is failed!'
                            return next(null, rest)
                        }
                        sys_user.find({
                            where: {
                                and: [{
                                        app_id: appid
                                    },
                                    {
                                        id: accessToken.userId
                                    }
                                ]
                            }
                        }, function (err, wxuser_results) {
                            if (err || wxuser_results.length <= 0) {
                                console.log(err)
                                rest.error = 'token failed';
                                rest.msg = 'access token is failed!'
                                return next(null, rest)
                            }

                            var wxuserData = wxuser_results[0];

                            //当微信用户的TOKEN已经绑定了手机以后
                            //并且用户登录的手机号与传过来的access token不一致
                            //不存在手机号的情况下，证明该微信未注册过，则绑定到登录的这个号上
                            if (wxuserData.mobile) {
                                if (wxuserData.mobile !== mobile) {
                                    rest.msg = 'sorry , wechat is bind another mobile!'
                                    rest.error = 'login failed!'
                                    return next(null, rest);
                                } else {
                                    rest.code = restful.statusCode.OK
                                    rest.msg = 'success'
                                    rest.error = '';
                                    rest.data = {
                                        token: token,
                                        user: wxuserData
                                    }
                                    smscodeData.used = true;
                                    smscodeData.save();
                                    return next(null, rest)
                                }
                            }

                            sys_user.find({
                                where: {
                                    and: [{

                                            app_id: appid
                                        },
                                        {
                                            mobile: mobile
                                        }
                                    ]
                                }
                            }, function (err, user_results) {

                                if (err) {
                                    console.log(err)
                                    rest.error = 'register error [sys_user.js-425]!'
                                    rest.msg = 'register failed!';
                                    return next(null, rest)
                                }

                                var userData = new sys_user;
                                if (!err && user_results.length > 0) {
                                    userData = user_results[0]
                                }

                                // 将微信号绑定到原手机号上
                                userData.wx_openid = wxuserData.wx_openid;
                                userData.wx_unionid = wxuserData.wx_unionid;
                                userData.wx_appid = wxuserData.wx_appid;
                                userData.exprise_in = wxuserData.exprise_in;
                                userData.wx_accesstoken = wxuserData.wx_accesstoken;
                                userData.wx_refresh_token = wxuserData.wx_refresh_token;
                                userData.mobile = mobile;
                                userData.username = mobile;
                                userData.app_id = appid;
                                userData.reg_date = new Date();
                                userData.last_login_date = new Date()
                                userData.reg_ip = ip
                                userData.last_login_ip = ip
                                sys_user_info.upsertWithWhere({
                                    sys_user_id: userData.id
                                }, {
                                    realname: realname
                                }, function () {
                                    console.log('realname register!')
                                })

                                //保存实例
                                userData.save(null, function (err, model) {
                                    wxuserData.destroy(); //销毁微信临时号
                                    //创建新的TOKEN返回
                                    model.createAccessToken(60 * 60 * 24, function (err, token) {
                                        rest.code = restful.statusCode.OK
                                        rest.msg = 'success'
                                        rest.error = ''
                                        rest.data = {
                                            token: token,
                                            user: model
                                        }
                                        smscodeData.used = true;
                                        smscodeData.save();

                                        sys_user.setPassword(userData.id, password);

                                        return next(null, rest)
                                    })
                                });
                            })
                        })
                    });
                } else {
                    // 非微信浏览器H5场景下，用户未得到accesstoken，直接进行注册

                    var userData = new sys_user();
                    userData.mobile = mobile;
                    userData.username = username;
                    userData.passowrd = password;
                    userData.app_id = appid;
                    userData.reg_date = new Date();
                    userData.last_login_date = new Date()
                    userData.reg_ip = ip
                    userData.last_login_ip = ip
                    sys_user_info.upsertWithWhere({
                        sys_user_id: userData.id
                    }, {
                        realname: realname
                    }, function () {
                        console.log('realname register!')
                    })
                    //保存实例
                    userData.save(null, function (err, model) {
                        //创建新的TOKEN返回
                        model.createAccessToken(60 * 60 * 24, function (err, token) {
                            rest.code = restful.statusCode.OK;
                            rest.msg = 'success'
                            rest.error = ''
                            rest.data = {
                                token: token,
                                user: wxuserData
                            }
                            smscodeData.used = true;
                            smscodeData.save();
                            userData.setPassword(password);
                            return next(null, rest)
                        })
                    });
                }
            })
        })
    }

    sys_user.loginWithPassword = loginWithPassword;
    sys_user.remoteMethod('loginWithPassword', {
        http: {
            path: '/pwdlogin/:appid',
            verb: 'post'
        },
        accepts: [{
            arg: 'access_token',
            type: 'string',
            http: {
                source: 'query'
            }
        }, {
            arg: 'appid',
            type: 'string',
            required: true,
            source: 'params'
        }, {
            arg: 'mobile',
            type: 'string',
            required: true
        }, {
            arg: 'password',
            type: 'string',
            required: true
        }, {
            arg: 'ip',
            type: 'string',
            http: function (ctx) {
                // 1\. Get the HTTP request object as provided by Express
                return ctx.req.ip;
            }
        }],
        returns: {
            arg: 'res',
            type: 'object'
        }
    })

    sys_user.loginWithSmscode = loginWithSmscode;
    sys_user.remoteMethod('loginWithSmscode', {
        http: {
            path: '/smslogin/:appid',
            verb: 'post'
        },
        accepts: [{
            arg: 'access_token',
            type: 'string',
            http: {
                source: 'query'
            }
        }, {
            arg: 'appid',
            type: 'string',
            required: true,
            source: 'params'
        }, {
            arg: 'mobile',
            type: 'string',
            required: true
        }, {
            arg: 'smscode',
            type: 'string',
            required: true
        }, {
            arg: 'ip',
            type: 'string',
            http: function (ctx) {
                // 1\. Get the HTTP request object as provided by Express
                return ctx.req.ip;
            }
        }],
        returns: {
            arg: 'res',
            type: 'object'
        }
    })
    sys_user.regWithMobile = regWithMobile;
    sys_user.remoteMethod('regWithMobile', {
        http: {
            path: '/register/:appid',
            verb: 'post'
        },
        accepts: [{
                arg: 'access_token',
                type: 'string',
                http: {
                    source: 'query'
                }
            },
            {
                arg: 'appid',
                type: 'string',
                required: true,
                source: 'params'
            },
            {
                arg: 'mobile',
                type: 'string',
                required: true
            },
            {
                arg: 'realname',
                type: 'string',
                required: true
            },
            {
                arg: 'password',
                type: 'string',
                required: true
            },
            {
                arg: 'confirm_pass',
                type: 'string',
                required: true
            },
            {
                arg: 'smscode',
                type: 'string',
                required: true
            }, {
                arg: 'ip',
                type: 'string',
                http: function (ctx) {
                    // 1\. Get the HTTP request object as provided by Express
                    return ctx.req.ip;
                }
            }
        ],
        returns: {
            arg: 'res',
            type: 'object'
        }
    })
}